/**
 * @fileOverview Koni
 * 一般图编辑器，适用于展示一般的网络拓扑关系。
 * @author huangtonger@aliyun.com
 */

const Page = require('../base/');
const Diagram = require('../diagram/');
const Util = require('./util/');

class Koni extends Diagram {
  constructor(inputCfg) {
    const cfg = {
      /**
       * graph cfg
       * @type {object|undefined}
       */
      graph: {
        modes: {
          default: [
            'panBlank', 'hoverGroupActived', 'keydownCmdWheelZoom',
            'clickEdgeSelected', 'clickNodeSelected', 'clickCanvasSelected', 'clickGroupSelected',
            'hoverNodeActived', 'hoverEdgeActived', 'hoverButton',
            'clickCollapsedButton', 'clickExpandedButton', 'wheelChangeViewport', 'keydownShiftMultiSelected',
            'dragNodeAddToGroup', 'dragOutFromGroup', 'panItem', 'hoverEdgeControlPoint', 'dragEdgeControlPoint'
          ],
          add: [ 'dragPanelItemAddNode', 'processAddEdge' ],
          readOnly: [ 'panCanvas' ],
          move: [ 'panCanvas' ],
          multiSelect: [ 'dragMultiSelect' ]
        },
        mode: 'default',
        defaultIntersectBox: 'circle',
        nodeDefaultShape: 'koni-base',
        edgeDefaultShape: 'koni-base',
        groupDefaultShape: 'koni-base',
        minZoom: 0.5,
        maxZoom: 2
      },
      orbit: {
        satellite: [
          'forkAndLink'
        ]
      },
      // edgeResizeable: false,
      anchorLink: false,
      noEndEdge: false
    };
    const mixinCfg = {};
    Util.mix(true, cfg, mixinCfg, inputCfg);
    super(cfg);
    this.isKoni = true;
  }
  bindEvent() {
    super.bindEvent();
    const graph = this.getGraph();
    graph.on('afterchange', ({ item, action, originModel, updateModel }) => {
      if (item && item.isEdge) {
        if (action === 'add' || action === 'remove') {
          const source = item.getSource();
          const target = item.getTarget();
          const parallelEdges = Util.getParallelEdges(source, target, true);
          parallelEdges.forEach(parallelEdge => {
            parallelEdge.update();
          });
        } else if (action === 'update') {
          const originSource = graph.find(originModel.source);
          const originTarget = graph.find(originModel.target);
          const originParallelEdges = Util.getParallelEdges(originSource, originTarget, true);
          let updateParallelEdges = [];
          originParallelEdges.forEach(parallelEdge => {
            parallelEdge.update();
          });
          if (Util.isNil(updateModel.target) && !Util.isNil(updateModel.source)) {
            const updateSource = graph.find(updateModel.source);
            updateParallelEdges = Util.getParallelEdges(updateSource, originTarget, true);
          } else if (!Util.isNil(updateModel.target) && Util.isNil(updateModel.source)) {
            const updateTarget = graph.find(updateModel.target);
            updateParallelEdges = Util.getParallelEdges(originSource, updateTarget, true);
          } else if (!Util.isNil(updateModel.target) && !Util.isNil(updateModel.source)) {
            const updateSource = graph.find(updateModel.source);
            const updateTarget = graph.find(updateModel.target);
            updateParallelEdges = Util.getParallelEdges(updateSource, updateTarget, true);
          }
          updateParallelEdges.forEach(parallelEdge => {
            parallelEdge.update();
          });
        }
      }
      if (action === 'changeData') {
        graph.getEdges().forEach(edge => {
          edge.update();
        });
      }
      graph.draw();
    });
  }
}
Page.setRegister(Koni, 'koni', 'diagram');
module.exports = Koni;
